package com.lsy.seckill.controller;
import cn.hutool.json.JSONUtil;
import com.lsy.seckill.RabbitMQ.SeckillSender;
import com.lsy.seckill.config.RabbitMQSeckillConfig;
import com.lsy.seckill.pojo.Order;
import com.lsy.seckill.pojo.SeckillGoods;
import com.lsy.seckill.pojo.SeckillMessage;
import com.lsy.seckill.pojo.User;
import com.lsy.seckill.service.GoodsService;
import com.lsy.seckill.service.OrderService;
import com.lsy.seckill.service.SeckillGoodsService;
import com.lsy.seckill.vo.SeckillGoodsVo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

//InitializingBean 实现该接口里面有一个方法
//该方法是在SeckillController类/对象的所有属性，都是初始化后，自动执行的

@Controller
@RequestMapping("/seckill")
public class SeckillController implements InitializingBean {
    @Resource
    private OrderService orderService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private SeckillGoodsService seckillGoodsService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private SeckillSender seckillSender;

    //定义map-记录秒杀商品是否还有库存
    private HashMap<Long, Boolean> entryStockMap = new HashMap<>();
    @RequestMapping("/doSeckill/{goodsId}")
    public String seckill(User user, @PathVariable Long goodsId, Model model){
        if (user==null){
            return "login";
        }
        model.addAttribute("user",user);
        ValueOperations valueOperations = redisTemplate.opsForValue();
//      判断是否还有库存 （内存标记）
        if (!entryStockMap.get(goodsId)){
            return "secKillFail";
        }
//        在redis里查看用户是否抢购过此商品
        Order order = (Order)valueOperations.get("order:" + user.getId() + ":" + goodsId);
        if (order!=null){
            //用户已经购买该商品
            return "secKillFail";
        }
        Long stockCount = valueOperations.decrement("seckillGoods:" + goodsId);
        if (stockCount<=0){
            //            //没有库存了
            entryStockMap.put(goodsId,false);
            return "secKillFail";//错误页面
        }

        SeckillMessage message = new SeckillMessage(user, goodsId);
        seckillSender.sendSeckillMessage(JSONUtil.toJsonStr(message));
        model.addAttribute("errmsg", "排队中...");
        return "secKillFail";
    }

//    该方法是在SeckillController类/对象的所有属性，都是初始化后，自动执行的
//    这里我们就可以将所有秒杀商品的库存量，加载到Redis
    @Override
    public void afterPropertiesSet() throws Exception {
        List<SeckillGoods> list = seckillGoodsService.list();
        if (list==null){
            return;
        }
        ValueOperations valueOperations = redisTemplate.opsForValue();
        for (SeckillGoods seckillGoods : list) {
            valueOperations.set("seckillGoods:"+seckillGoods.getGoodsId(),seckillGoods.getStockCount());

            //初始化map
            //如果goodsId : false 表示没有库存
            //如果goodsId : true 表示有库存
            entryStockMap.put(seckillGoods.getGoodsId(), true);

        }
    }

}
